import axios from 'axios'
import { useStore } from '@/store'
import { showLoading as VantLoading, showToast } from './utils'

const IS_PROD = import.meta.env.PROD
const TIME_OUT = 1000 * 180

const http = axios.create({
  baseURL: '',
  timeout: TIME_OUT,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
})

// Loding实例
const loading = {
  count: 0,
  context: null,
}

/**
 * 显示Loading
 */
const showLoading = (loadingText = 'Loading') => {
  loading.count += 1

  if (loading.count === 1) {
    loading.context = VantLoading(loadingText)
  }
}

/**
 * 检查是否需要隐藏Loading
 */
const checkHideLoading = () => {
  loading.count -= 1

  if (loading.count <= 0) {
    loading.count = 0
    loading.context?.close()
  }
}

/**
 * 请求结束回调
 */
const requestEnd = (res) => {
  setTimeout(() => {
    const store = useStore()

    const { code, msg, message } = res

    if ([401, 403].includes(code)) {
      // store.setToken('')
      // setTimeout(() => {
      //   location.reload()
      // }, 2000)
    }

    if (code !== 200 && typeof code !== 'undefined') {
      showToast(msg || message || '系统异常，请重试')
    }
  }, 0)
}

// ---- 请求拦截 ----
http.interceptors.request.use(
  (config) => {
    const store = useStore()
    const params = config[config.method == 'get' ? 'params' : 'data'] || {}

    // 判断是否需要显示loading
    const loading =
      typeof params.get === 'function' ? params.get('loading') : params.loading

    params.loading =
      typeof loading === 'boolean'
        ? loading
        : loading === 'false'
        ? false
        : true

    if (params.loading) {
      config.loading = params.loading
      showLoading(params.loadingText)
    }

    // Token验证
    config.headers['Authorization'] = store.token || ''

    // 移除多余参数
    delete params.loading
    delete params.loadingText

    return config
  },
  (err) => {
    return Promise.reject(err)
  }
)

// ---- 响应拦截 ----
http.interceptors.response.use(
  (res) => {
    if (res.config.loading) {
      checkHideLoading()
    }

    requestEnd(res.data)

    return res.data
  },
  (err) => {
    if (err.config.loading) {
      checkHideLoading()
    }

    requestEnd(err.response.data)

    return Promise.reject(err)
  }
)

// 封装增删改查方法
const request = {}
const methods = ['get', 'post', 'put', 'delete']

methods.forEach((method) => {
  request[method] = (url = '', params = {}, headers = {}, isQuery = false) => {
    return new Promise((resolve, reject) => {
      const options = {
        method: method === 'del' ? 'delete' : method,
        url: IS_PROD
          ? url.replace('/remote1', '').replace('/remote2', '')
          : url,
        headers,
      }

      options[method == 'get' || isQuery ? 'params' : 'data'] = params

      http(options)
        .then((res) => {
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }
})

export default request
